﻿/// <reference path="../Core.ts" />

module Supernova {

    export class GeneratorProfile {

        public static SCHEMA_VERSION = 20150803;

        public name: string = '';

        public systems = {
            count: { perPerson: 0, maximum: 0 },
            minPlanets: 1,
            maxPlanets: 9,
            chanceNoPlanets: 0.15,
            minPlanetDistance: 0.2,
            maxPlanetDistance: 1,
            maxPopulation: 20,
            chanceBarren: 0.4,
            chanceHabitable: 0.3,
            chanceGas: 0.3,
            namingScheme: StarNamingScheme.pretty
        };

        public home = {
            systemDesirabilityPercentile: 0.5,
            startingPopulation: 5
        };

        public gold = {
            rate: { noComms: 0.1, withComms: 0.5, withMines: 15 }
        };

        public science = {
            rate: { noFacility: 0.012, withFacility: 0.03 },
            perExploredSystem: 10
        };

        public resources = {
            initialScience: 50,
            initialGold: 1000,
            goldChanceOnBarrenPlanets: 0.3,
            goldMaximum: 10000,
        };

        public goodies = {
            chanceGold: 0.5,
            minPerSystemMultiplier: 0.7,
            maxPerSystemMultiplier: 1.2,
            values: {
                gold: [50, 100, 100, 100, 100, 200, 200, 500],
                science: [5, 10, 10, 10, 10, 10, 20, 20, 50]
            },
        };

        public wrecks = {
            perHumanPlayer: 4,
            perSystem: 0.5,
            perHumanPlayerNearHomeSystem: 2,
            inSystemDistanceMultiplier: 2,
            upgradesInSystem: 1,
            minUpgradesOutsideSystem: 2,
            maxUpgradesOutsideSystem: 3
        };

        public ai = {
            minimumNests: 0,
            spawn: { minInterval: 20, maxInterval: 40, initialWait: 10, timePerLevel: 60, progressionFactor: 1.0 }
        };

        public traitPoints: number = 0;

        constructor(name: string) {
            this.name = name;
        }

        public toJson(): any {
            return {
                schemaVersion: GeneratorProfile.SCHEMA_VERSION,
                name: this.name,
                systems: {
                    count: {
                        perPerson: this.systems.count.perPerson,
                        maximum: this.systems.count.maximum
                    },
                    minPlanets: this.systems.minPlanets,
                    maxPlanets: this.systems.maxPlanets,
                    chanceNoPlanets: this.systems.chanceNoPlanets,
                    minPlanetDistance: this.systems.minPlanetDistance,
                    maxPlanetDistance: this.systems.maxPlanetDistance,
                    maxPopulation: this.systems.maxPopulation,
                    chanceBarren: this.systems.chanceBarren,
                    chanceHabitable: this.systems.chanceHabitable,
                    chanceGas: this.systems.chanceGas,
                    namingSchema: this.systems.namingScheme
                },
                home: {
                    systemDesirabilityPercentile: this.home.systemDesirabilityPercentile,
                    startingPopulation: this.home.startingPopulation
                },
                gold: {
                    rate: {
                        noComms: this.gold.rate.noComms,
                        withComms: this.gold.rate.withComms,
                        withMines: this.gold.rate.withMines
                    }
                },
                science: {
                    rate: {
                        noFacility: this.science.rate.noFacility,
                        withFacility: this.science.rate.withFacility
                    },
                    perExploredSystem: this.science.perExploredSystem
                },
                resources: {
                    initialScience: this.resources.initialScience,
                    initialGold: this.resources.initialGold,
                    goldChanceOnBarrenPlanets: this.resources.goldChanceOnBarrenPlanets,
                    goldMaximum: this.resources.goldMaximum,
                },
                goodies: {
                    chanceGold: this.goodies.chanceGold,
                    minPerSystemMultiplier: this.goodies.minPerSystemMultiplier,
                    maxPerSystemMultiplier: this.goodies.maxPerSystemMultiplier,
                    values: {
                        gold: this.goodies.values.gold,
                        science: this.goodies.values.science
                    },
                },
                wrecks: {
                    perHumanPlayer: this.wrecks.perHumanPlayer,
                    perSystem: this.wrecks.perSystem,
                    perHumanPlayerNearHomeSystem: this.wrecks.perHumanPlayerNearHomeSystem,
                    inSystemDistanceMultiplier: this.wrecks.inSystemDistanceMultiplier,
                    upgradesInSystem: this.wrecks.upgradesInSystem,
                    minUpgradesOutsideSystem: this.wrecks.minUpgradesOutsideSystem,
                    maxUpgradesOutsideSystem: this.wrecks.maxUpgradesOutsideSystem
                },
                ai: {
                    minimumNests: this.ai.minimumNests,
                    spawn: {
                        minInterval: this.ai.spawn.minInterval,
                        maxInterval: this.ai.spawn.maxInterval,
                        initialWait: this.ai.spawn.initialWait,
                        timePerLevel: this.ai.spawn.timePerLevel,
                        progressionFactor: this.ai.spawn.progressionFactor
                    }
                },
                traitPoints: this.traitPoints
            };
        }

        public static fromJson(json: any): GeneratorProfile {
            if (json.schemaVersion != GeneratorProfile.SCHEMA_VERSION) {
                throw 'The schema of the specified profile is out of date or invalid.';
            }
            var profile = new GeneratorProfile(json.name);
            profile.systems.count.perPerson = parseFloat(json.systems.count.perPerson);
            profile.systems.count.maximum = parseFloat(json.systems.count.maximum);
            profile.systems.minPlanets = parseFloat(json.systems.minPlanets);
            profile.systems.maxPlanets = parseFloat(json.systems.maxPlanets);
            profile.systems.chanceNoPlanets = parseFloat(json.systems.chanceNoPlanets);
            profile.systems.minPlanetDistance = parseFloat(json.systems.minPlanetDistance);
            profile.systems.maxPlanetDistance = parseFloat(json.systems.maxPlanetDistance);
            profile.systems.maxPopulation = parseFloat(json.systems.maxPopulation);
            profile.systems.chanceBarren = parseFloat(json.systems.chanceBarren);
            profile.systems.chanceHabitable = parseFloat(json.systems.chanceHabitable);
            profile.systems.chanceGas = parseFloat(json.systems.chanceGas);
            profile.systems.namingScheme = parseFloat(json.systems.namingScheme);
            profile.home.systemDesirabilityPercentile = parseFloat(json.home.systemDesirabilityPercentile);
            profile.home.startingPopulation = parseFloat(json.home.startingPopulation);
            profile.gold.rate.noComms = parseFloat(json.gold.rate.noComms);
            profile.gold.rate.withComms = parseFloat(json.gold.rate.withComms);
            profile.gold.rate.withMines = parseFloat(json.gold.rate.withMines);
            profile.science.rate.noFacility = parseFloat(json.science.rate.noFacility);
            profile.science.rate.withFacility = parseFloat(json.science.rate.withFacility);
            profile.science.perExploredSystem = parseFloat(json.science.perExploredSystem);
            profile.resources.initialScience = parseFloat(json.resources.initialScience);
            profile.resources.initialGold = parseFloat(json.resources.initialGold);
            profile.resources.goldChanceOnBarrenPlanets = parseFloat(json.resources.goldChanceOnBarrenPlanets);
            profile.resources.goldMaximum = parseFloat(json.resources.goldMaximum);
            profile.goodies.chanceGold = parseFloat(json.goodies.chanceGold);
            profile.goodies.minPerSystemMultiplier = parseFloat(json.goodies.minPerSystemMultiplier);
            profile.goodies.maxPerSystemMultiplier = parseFloat(json.goodies.maxPerSystemMultiplier);
            profile.goodies.values.gold = [];
            for (var i = 0; i < json.goodies.values.gold.length; i++) {
                profile.goodies.values.gold.push(parseFloat(json.goodies.values.gold[i]));
            }
            profile.goodies.values.science = [];
            for (var i = 0; i < json.goodies.values.gold.length; i++) {
                profile.goodies.values.science.push(parseFloat(json.goodies.values.science[i]));
            }            
            profile.wrecks.perHumanPlayer = parseFloat(json.wrecks.perHumanPlayer);
            profile.wrecks.perSystem = parseFloat(json.wrecks.perSystem);
            profile.wrecks.perHumanPlayerNearHomeSystem = parseFloat(json.wrecks.perHumanPlayerNearHomeSystem);
            profile.wrecks.inSystemDistanceMultiplier = parseFloat(json.wrecks.inSystemDistanceMultiplier);
            profile.wrecks.upgradesInSystem = parseFloat(json.wrecks.upgradesInSystem);
            profile.wrecks.minUpgradesOutsideSystem = parseFloat(json.wrecks.minUpgradesOutsideSystem);
            profile.wrecks.maxUpgradesOutsideSystem = parseFloat(json.wrecks.maxUpgradesOutsideSystem);
            profile.ai.minimumNests = parseFloat(json.ai.minimumNests);
            profile.ai.spawn.minInterval = parseFloat(json.ai.spawn.minInterval);
            profile.ai.spawn.maxInterval = parseFloat(json.ai.spawn.maxInterval);
            profile.ai.spawn.initialWait = parseFloat(json.ai.spawn.initialWait);
            profile.ai.spawn.timePerLevel = parseFloat(json.ai.spawn.timePerLevel);
            profile.ai.spawn.progressionFactor = parseFloat(json.ai.spawn.progressionFactor);
            profile.traitPoints = parseFloat(json.traitPoints);
            return profile;
        }

    }

}